package com.yanyu.space.common.log.support;

import com.yanyu.space.common.log.handler.LogFactory;
import com.yanyu.space.common.log.handler.LogWorkerContext;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.sleuth.Span;
import org.springframework.cloud.sleuth.Tracer;
import org.springframework.core.Ordered;

/**
 * @author yanyu
 */
@Aspect
@RefreshScope
@Slf4j
public class LogXxljobAspect implements Ordered {

    private Tracer tracer;

    @Value("${space.log.xxljob.enabled:true}")
    private String xxljobEnabled;

    public LogXxljobAspect(Tracer tracer) {
        this.tracer = tracer;
    }

    @Around("execution (@com.yanyu.space.common.core.annotation.XxlJob  * *.*(..))")
    public Object traceBackgroundThread(final ProceedingJoinPoint pjp) throws Throwable {
        // 类名
        String className = pjp.getTarget().getClass().getName();
        // 方法名
        String methodName = pjp.getSignature().getName();
        Span parentSpan = this.tracer.nextSpan().event("sr").tag("class", className).tag("method", methodName).tag("xxljob", "xxljob").name("xxljob").start();
        try (Tracer.SpanInScope spanInScope = this.tracer.withSpan(parentSpan)) {
            Span childSpan = tracer.nextSpan(parentSpan).event("cs").name("xxljob_1").start();
            try (LogWorkerContext logWorkerContext = LogFactory.getInstance().start(this.tracer.currentSpan().context())) {
                return proceed(pjp);
            } finally {
                if (StringUtils.isNoneBlank(xxljobEnabled) && StringUtils.equalsAnyIgnoreCase(xxljobEnabled, "true")) {
                    childSpan.end();
                } else {
                    childSpan.abandon();
                }
            }
        } finally {
            if (StringUtils.isNoneBlank(xxljobEnabled) && StringUtils.equalsAnyIgnoreCase(xxljobEnabled, "true")) {
                parentSpan.end();
            } else {
                parentSpan.abandon();
            }
        }
    }

    @Override
    public int getOrder() {
        return Ordered.LOWEST_PRECEDENCE;
    }

    private Object proceed(final ProceedingJoinPoint pjp) {
        Object result = null;
        try {
            result = pjp.proceed();
        } catch (Throwable e) {
            log.error("{}", e.getMessage(), e);
        }
        return result;
    }
}
